/*
 * This source code is part of TWaver 4.0
 *
 * Serva Software PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 * Copyright 2002 - 2011 Serva Software. All rights reserved.
 */

package demo.chart.radar;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import twaver.Element;
import twaver.Generator;
import twaver.Node;
import twaver.TDataBox;
import twaver.TUIManager;
import twaver.TWaverConst;
import twaver.TWaverUtil;
import twaver.VisibleFilter;
import twaver.chart.RadarAxis;
import twaver.chart.RadarChart;
import twaver.list.TList;
import twaver.swing.TableLayout;
import demo.DemoPane;

public class RadarChartDemo extends DemoPane {
	
	private TDataBox box = new TDataBox();
	
	private String countries[] = { "Canada", "China", "France", "Japan", "United States" };
	private Color colors[] = { Color.RED, Color.ORANGE, Color.GREEN, new Color(153, 0, 153), Color.BLUE };
	private double[] inflation = { 2.4, 10.1, 1.7, -0.1, 2.5 };
	private double[] area = { 9976140, 9596960, 547030, 377835, 9372210 };
	private double[] population = { 28860271, 1210004956, 58317450, 125449703, 266476278 };
	private double[] gdp = { 694000, 3500000, 1173000, 2679200, 7247700 };
	private double[] growth = { 1.06, 0.98, 0.34, 0.21, 0.91 };
	
	private Image worldImage = TWaverUtil.getImage("/demo/chart/radar/world.gif");
	private String listIconUrl = "/demo/resource/images/flag.png";
	
	private RadarChart chart = new RadarChart(box) {
		protected void paintBackground(Graphics2D g) {
			super.paintBackground(g);
			Dimension dim = chart.getSize();
			g.drawImage(worldImage, 0, 0, (int) (dim.width * this.getXZoom()), (int) (dim.height * this.getYZoom()), null);
		}

		protected String getScaleValueText(Object obj, int index) {
			double axisMin = 0;
			double axisMax = 0;
			if (obj instanceof RadarAxis) {
				RadarAxis raxis = (RadarAxis) obj;
				if (!raxis.isAxisTextVisible()) {
					return null;
				}
				axisMin = raxis.getMinValue();
				axisMax = raxis.getMaxValue();
			}
			else {
				double avgValue = (chart.getScaleMaxValue() - chart.getScaleMinValue()) / this.getScaleMajorCount();
				String value = getFormat().format(avgValue * index + chart.getScaleMinValue());
				return value;
			}
			double avgValue;
			if (axisMax == axisMin) {
				avgValue = axisMax;
			}
			else {
				avgValue = (axisMax - axisMin) / this.getScaleMajorCount();
			}

			double number = avgValue * index + axisMin;
			if (obj instanceof RadarAxis) {
				RadarAxis axis = (RadarAxis) obj;
				if (axis.getText().startsWith("Population") || axis.getText().startsWith("Area") || axis.getText().startsWith("GDP")) {
					number = number / 1000000;
				}
			}

			String value = getFormat().format(number);
			return value;
		}
	};

	public RadarChartDemo() {
		intBox();
		initChart();
		initGUI();
	}

	private void initGUI() {
		this.setLayout(new BorderLayout());
		this.add(chart, BorderLayout.CENTER);
		this.add(getControlPanel(), BorderLayout.EAST);
	}

	private JPanel createSliderPanel(final JSlider slider) {
		JPanel panel = new JPanel(new BorderLayout());
		panel.add(slider, BorderLayout.CENTER);
		final JTextField field = new JTextField();
		slider.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				field.setText(slider.getValue() + "");
			}
		});
		field.setEditable(false);
		field.setPreferredSize(new Dimension(30, 20));
		panel.add(field, BorderLayout.EAST);
		return panel;
	}

	private JPanel getControlPanel() {
		JPanel panel = new JPanel(new BorderLayout(2, 2));
		panel.setBorder(BorderFactory.createEmptyBorder(5, 6, 5, 5));
		double[] rows = { TableLayout.PREFERRED,
							TableLayout.PREFERRED,
							TableLayout.PREFERRED,
							TableLayout.PREFERRED,
							TableLayout.PREFERRED,
							TableLayout.PREFERRED,
							TableLayout.PREFERRED };
		double[] cols = { TableLayout.PREFERRED, TableLayout.PREFERRED };
		JPanel controlPanel = new JPanel(new TableLayout(cols, rows, 2, 5));
		int rowIndex = 0;

		final JSlider angleSlider = new JSlider(0, 360);
		angleSlider.setValue(0);
		angleSlider.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				chart.setAxisStartAngle(angleSlider.getValue());
			}
		});

		angleSlider.setMajorTickSpacing(45);
		angleSlider.setPaintTicks(true);
		
		controlPanel.add(getRightLabel("StartAngle:"), "0," + rowIndex + ",0," + rowIndex);
		rowIndex++;
		controlPanel.add(createSliderPanel(angleSlider), "0," + rowIndex + ",1," + rowIndex);
		rowIndex++;
		angleSlider.setValue(270);

		final JSlider majorSlider = new JSlider(0, 10);
		majorSlider.setValue(0);
		majorSlider.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				chart.setScaleMajorCount(majorSlider.getValue());
			}
		});
		
		majorSlider.setMajorTickSpacing(1);
		majorSlider.setPaintTicks(true);

		controlPanel.add(getRightLabel("MajorCount:"), "0," + rowIndex + ",0," + rowIndex);
		rowIndex++;
		controlPanel.add(createSliderPanel(majorSlider), "0," + rowIndex + ",1," + rowIndex);
		rowIndex++;
		majorSlider.setValue(5);
		
		JPanel inflexionPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
		inflexionPanel.add(getRightLabel("Inflexion:"), "0," + rowIndex + ",0," + rowIndex);
		final JComboBox inflexionComboBox = new JComboBox();
		inflexionComboBox.addItem("Circle");
		inflexionComboBox.addItem("Diamond");
		inflexionComboBox.addItem("Rectangle");
		inflexionComboBox.addItem("Triangle");
		inflexionComboBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String item = inflexionComboBox.getSelectedItem().toString();
				if ("Circle".equals(item)) {
					chart.setInflexionStyle(TWaverConst.INFLEXION_STYLE_CIRCLE);
				}
				else if ("Diamond".equals(item)) {
					chart.setInflexionStyle(TWaverConst.INFLEXION_STYLE_DIAMOND);
				}
				else if ("Rectangle".equals(item)) {
					chart.setInflexionStyle(TWaverConst.INFLEXION_STYLE_RECTANGLE);
				}
				else if ("Triangle".equals(item)) {
					chart.setInflexionStyle(TWaverConst.INFLEXION_STYLE_TRIANGLE);
				}
			}
		});
		inflexionPanel.add(inflexionComboBox);
		controlPanel.add(inflexionPanel, "0," + rowIndex + ",1," + rowIndex);
		rowIndex++;

		JPanel axisPanel = new JPanel(new GridLayout(4, 2));
		final JCheckBox axisCheckBox = new JCheckBox("AxisVisible");
		axisCheckBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				chart.setAxisVisible(axisCheckBox.isSelected());
			}
		});
		axisCheckBox.setSelected(true);
		axisPanel.add(axisCheckBox);

		final JCheckBox axisTextCheckBox = new JCheckBox("AxisText");
		axisTextCheckBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				chart.setAxisTextVisible(axisTextCheckBox.isSelected());
			}
		});
		axisPanel.add(axisTextCheckBox);

		final JCheckBox scaleTextCheckBox = new JCheckBox("ScaleText");
		scaleTextCheckBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				chart.setScaleMajorTextVisible(scaleTextCheckBox.isSelected());
			}
		});
		scaleTextCheckBox.setSelected(true);
		axisPanel.add(scaleTextCheckBox);

		final JCheckBox ringVisibleCheckBox = new JCheckBox("Ring");
		ringVisibleCheckBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				chart.setRingVisible(ringVisibleCheckBox.isSelected());
			}
		});
		ringVisibleCheckBox.setSelected(true);
		axisPanel.add(ringVisibleCheckBox);
		
		final JCheckBox inflexionCheckBox = new JCheckBox("Inflexion");
		inflexionCheckBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				chart.setInflexionVisible(inflexionCheckBox.isSelected());
			}
		});
		inflexionCheckBox.setSelected(true);
		axisPanel.add(inflexionCheckBox);
		
		final JCheckBox lineBox = new JCheckBox("Line");
		lineBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				chart.setLineVisible(lineBox.isSelected());
			}
		});
		lineBox.setSelected(true);
		axisPanel.add(lineBox);
		
		final JCheckBox AreaFillBox = new JCheckBox("AreaFill");
		AreaFillBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				chart.setAreaFill(AreaFillBox.isSelected());
			}
		});
		AreaFillBox.setSelected(true);
		axisPanel.add(AreaFillBox);

		controlPanel.add(axisPanel, "0," + rowIndex + ",1," + rowIndex);
		rowIndex++;

		panel.add(controlPanel, BorderLayout.NORTH);

		final TList list = new TList();
		list.setTListSelectionMode(TList.CHECK_SELECTION);
		list.setPaintSelectedStateWhenChecked(false);

		int count = countries.length;
		for (int i = 0; i < count; i++) {
			Node element = new Node("" + i);
			element.setName(countries[i]);
			list.getDataBox().addElement(element);
		}
		list.getDataBox().getSelectionModel().selectAll();

		list.setElementIconGenerator(new Generator() {
			public Object generate(Object object) {
				Element element = (Element) object;
				int index = Integer.parseInt(element.getID().toString());
				return TWaverUtil.getImageIcon(listIconUrl, colors[index]);
			}
		});
		list.addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent e) {
				chart.publishData();
			}
		});
		
		panel.add(new JScrollPane(list), BorderLayout.CENTER);

		chart.addVisibleFilter(new VisibleFilter() {
			public boolean isVisible(Element element) {
				Element listElement = list.getDataBox().getElementByID(element.getID());
				return listElement.isSelected();
			}
		});

		return panel;
	}
	
	public JLabel getRightLabel(String text){
		JLabel label = new JLabel(text);
		label.setHorizontalAlignment(JLabel.LEFT);
		return label;
	}

	private void initChart() {
		chart.setAxisTextFont(TUIManager.getDefaultPlainFont());
		chart.setScaleMinCount(1);
		chart.setShapeFillGradient(false);
		chart.setScaleMajorTextFont(TUIManager.getDefaultPlainFont());
		chart.setRingMajorStroke(TWaverConst.STROKE_SOLID_THINNEST);

		chart.setBackgroundVisible(true);
		chart.setBackgroundFillColor(Color.DARK_GRAY);
		chart.setAxisColor(Color.GREEN.darker());
		chart.setRingMajorColor(Color.GREEN.darker());
		
		chart.setAxisTextVisible(false);

		RadarAxis axis = new RadarAxis("Inflation", -5, 15);
		chart.addAxis(axis);
		axis = new RadarAxis("Area(Millions)", 0, 20000000);
		chart.addAxis(axis);
		axis = new RadarAxis("Population(Millions)", 0, 2000000000);
		chart.addAxis(axis);
		axis = new RadarAxis("GDP(Thousands)", 0, 8000000);
		chart.addAxis(axis);
		axis = new RadarAxis("Growth", 0, 2);
		chart.addAxis(axis);
		chart.setScaleMajorTextVisible(true);
		chart.setScaleMajorTextColor(new Color(50, 100, 0));
	}

	private void intBox() {
		int count = countries.length;
		for (int i = 0; i < count; i++) {
			Element element = new Node("" + i);
			if (i == 0) {
				element.setSelected(true);
			}
			element.setName(countries[i]);
			element.addChartValue(inflation[i]);
			element.addChartValue(area[i]);
			element.addChartValue(population[i]);
			element.addChartValue(gdp[i]);
			element.addChartValue(growth[i]);
			element.putChartColor(colors[i]);
			box.addElement(element);
		}
	}
}